package Controllers;

import java.rmi.RemoteException;

import Models.BoardModel2D;
import Models.Player;
import Models.Point2D;
import Models.StandardBoardModel2D;
import Models.StandardPoint2D;


public class BoardController implements BoardControllerInterface {

	

	@Override
	public boolean movePiece(Point2D startPoint, Point2D endPoint,
			BoardModel2D board) throws RemoteException {
		
		if (board.getPiece(startPoint) != null) {
			if (board.getPiece(startPoint).canJump() || !isBlockingPiece(startPoint, endPoint, board)) {
			if (board.getPiece(endPoint) == null) {
				if (board.getPiece(startPoint).canPieceMoveNotify(startPoint, endPoint)) {
					 
					board.setPiece(endPoint, board.getPiece(startPoint));
					board.setPiece(startPoint, null);
						return true;
					
					}
				}
			else {
				if (!board.getPiece(startPoint).getPlayer().equals(board.getPiece(endPoint).getPlayer())) {
					if (board.getPiece(startPoint).canPieceCaptureNotify(startPoint, endPoint)) {
					
					board.setPiece(endPoint, board.getPiece(startPoint));
					board.setPiece(startPoint, null);
						return true;
						}
					}
				}
			}
		}
		
		return false;
	}

	@Override
	public void resetStartingPotition(BoardModel2D boardModel, Player player1, Player player2)
			throws RemoteException {
		
		boardModel.setPiece(new StandardPoint2D(0, 7), RookController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(1, 7), KnightController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(2, 7), BishopController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(3, 7), KingController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(4, 7), QueenController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(5, 7), BishopController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(6, 7), KnightController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(7, 7), RookController.getNew(player2));
		
		boardModel.setPiece(new StandardPoint2D(0, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(1, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(2, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(3, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(4, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(5, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(6, 6), PawnController.getNew(player2));
		boardModel.setPiece(new StandardPoint2D(7, 6), PawnController.getNew(player2));
		

		boardModel.setPiece(new StandardPoint2D(0, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(1, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(2, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(3, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(4, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(5, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(6, 1), PawnController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(7, 1), PawnController.getNew(player1));
		

		boardModel.setPiece(new StandardPoint2D(0, 0), RookController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(1, 0), KnightController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(2, 0), BishopController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(3, 0), KingController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(4, 0), QueenController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(5, 0), BishopController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(6, 0), KnightController.getNew(player1));
		boardModel.setPiece(new StandardPoint2D(7, 0), RookController.getNew(player1));
		
		
	}
	
	private boolean isBlockingPiece(Point2D startPosition, Point2D endPosition, BoardModel2D board) {
		
		
		
		if (startPosition.getX() == endPosition.getX() && (endPosition.getY() > startPosition.getY())) {
			for (int y = startPosition.getY() + 1; y < endPosition.getY(); y ++) {
				if (board.getPiece(new StandardPoint2D (startPosition.getX(), y)) != null) {
					return true;
				}
				}
			
		}
		
		else if (startPosition.getX() == endPosition.getX() && (endPosition.getY() < startPosition.getY())) {
			for (int y = startPosition.getY() - 1; y > endPosition.getY(); y --) {
				if (board.getPiece(new StandardPoint2D (startPosition.getX(), y)) != null) {
					return true;
				}
				}
		}
		else if (startPosition.getY() == endPosition.getY() && (endPosition.getX() > startPosition.getX())) {
			for (int x = startPosition.getX() + 1; x < endPosition.getX(); x++) {
				if (board.getPiece(new StandardPoint2D (x, startPosition.getY())) != null) {
					return true;
				}
				}
		}
		else if (startPosition.getY() == endPosition.getY() && (endPosition.getX() < startPosition.getX())) {
			for (int x = startPosition.getX() - 1; x > endPosition.getX(); x--) {
				if (board.getPiece(new StandardPoint2D (x, startPosition.getY())) != null) {
					return true;
				}
				}
		}
		else if ((endPosition.getX() > startPosition.getX()) && (endPosition.getY() > startPosition.getY())){
			int y = startPosition.getY();
			for (int x = startPosition.getX() + 1; x < endPosition.getX(); x++) {
				y ++;
				if (board.getPiece(new StandardPoint2D (x, y)) != null) {
					return true;
					}
				}
		}
		
		else if ((endPosition.getX() > startPosition.getX()) && (endPosition.getY() < startPosition.getY())){
			int y = startPosition.getY();
			for (int x = startPosition.getX() + 1; x < endPosition.getX(); x++) {
				y --;
				if (board.getPiece(new StandardPoint2D (x, y)) != null) {
					return true;
					}
				}
		}
		
		else if ((endPosition.getX() < startPosition.getX()) && (endPosition.getY() < startPosition.getY())){
			int y = startPosition.getY();
			for (int x = startPosition.getX() - 1; x > endPosition.getX(); x--) {
				y --;
				if (board.getPiece(new StandardPoint2D (x, y)) != null) {
					return true;
					}
				}
		}
		
		else if ((endPosition.getX() < startPosition.getX()) && (endPosition.getY() > startPosition.getY())){
			int y = startPosition.getY();
			for (int x = startPosition.getX() - 1; x > endPosition.getX(); x--) {
				y ++;
				if (board.getPiece(new StandardPoint2D (x, y)) != null) {
					return true;
					}
				}
		}
		return false;
}

	@Override
	public boolean canMoveNotify(Point2D from, Point2D to, BoardModel2D board)
			throws RemoteException {
		
		return movePiece(from, to, board);
	}
	
	public static BoardModel2D getNew() {
		BoardModel2D board = new StandardBoardModel2D();
		BoardControllerInterface boardController = new BoardController();
		board.addCanMoveListener(boardController);
		
		return board;
		
	}

	
	

}
